﻿using System;
using System.Text;

namespace FuzzScript
{
    /// <summary>
    /// Set Clause class implements antecedent and consequent set clause such as "VARIABLE is SET".
    /// SetClause objects will have only ine sibling: a reference to the actual fuzzy set node referred
    /// to by the clause.
    /// </summary>
    public abstract class SetClause : Node
    {
        /// <summary>
        /// Name of the fuzzy variable in this clause
        /// </summary>
        protected string m_sVariableName;

        /// <summary>
        /// Gets the fuzzy variable in this clause
        /// </summary>
        public string VariableName
        {
            get { return m_sVariableName; }
        }

        /// <summary>
        /// Name of the fuzzy set in this clause
        /// </summary>
        protected string m_sSetName;

        /// <summary>
        /// Gets the fuzzy set in this clause
        /// </summary>
        public string SetName
        {
            get { return m_sSetName; }
        }

        /// <summary>
        /// Default constructor is private
        /// </summary>
        private SetClause() { }

        /// <summary>
        /// Constructor. sets the node sibling given the names of the variable and set
        /// </summary>
        /// <param name="p_sVariableName">The fuzzy variable name</param>
        /// <param name="p_sSetName">The fuzzy set name</param>
        public SetClause(string p_sVariableName, string p_sSetName)
        {
            // Initialize the node to have one sibling
            base.m_SiblingNodes.Add(null);

            // save the variable ans set names
            m_sVariableName = p_sVariableName;
            m_sSetName = p_sSetName;
            
            // try to retreive the set node from the symbol table. Throw an Exception on fail
            try
            {
                m_SiblingNodes[0] = (SymbolTable.Instance.Get(
                    SymbolTable.AttributeFuzzySet(m_sVariableName, m_sSetName)));
            }
            catch (Exception e)
            {
                throw new Exception("Error in Clause: " + m_sVariableName + " is " + m_sSetName, e);
            }
        }

        /// <summary>
        /// Returns a sting representation of the node
        /// </summary>
        /// <returns></returns>
        public override string ToString()
        {
            return m_sVariableName + " is " + m_sSetName;
        }

        /// <summary>
        /// SetClauses cannot be executed directly
        /// </summary>
        /// <returns></returns>
        public override double Execute()
        {
            throw new NotImplementedException();
        }

        /// <summary>
        /// Siblings cannot be added directly
        /// </summary>
        /// <param name="p_SiblingNode"></param>
        public override void AddSibling(INode p_SiblingNode)
        {
            throw new NotImplementedException("SetClause error. Siblings cannot be added");
        }

        public override string Generate()
        {
            return SymbolTable.AttributeSetDOM(m_sVariableName, m_sSetName);
        }
    }
}